<template>
  <div class="app-container">
    <!-- 搜索区域 -->
    <div class="search-container">
      <el-form ref="queryFormRef" :model="queryParams" :inline="true">
        <el-form-item label="数据库" prop="dbId">
          <el-tree-select
            v-model="queryParams.dbId"
            placeholder="选择数据库"
            :data="dbSourceOptions"
            filterable
            check-strictly
            :render-after-expand="false"
            style="width: 250px"
          />
        </el-form-item>

        <el-form-item class="search-buttons">
          <el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
          <el-button icon="Refresh" @click="handleResetQuery">重置</el-button>
        </el-form-item>
      </el-form>
    </div>

    <el-card shadow="hover" class="data-table">
      <div class="data-table__toolbar">
        <div class="data-table__toolbar--actions">
          <el-button type="success" plain @click="updateBinLog">同步BinLog</el-button>
          <!-- 右侧提示 -->
          <span class="data-table__tip">
            Tips:
            1.如果想查询最新SQL语句，请解析最新BinLog文件。2.首次解析可能会比较慢，请耐心等待！
          </span>
        </div>
      </div>

      <el-table
        ref="dataTableRef"
        v-loading="loading"
        :data="binLogList"
        highlight-current-row
        border
        class="data-table__content"
        @selection-change="handleSelectionChange"
      >
        <el-table-column label="数据源" prop="dbNameAlias" align="center" min-width="150" />
        <el-table-column label="数据库" prop="dbName" align="center" width="120" />
        <el-table-column label="BinLog文件名" prop="fileName" align="center" width="180" />
        <el-table-column label="文件大小（KB）" prop="fileSize" align="center" width="150" />
        <el-table-column label="上次解析位置" prop="prevPosition" align="center" width="150" />
        <el-table-column label="最新位置" prop="latestPosition" align="center" width="150" />
        <el-table-column label="解析耗时平均值(秒)" prop="avgSqlTime" align="center" width="180" />
        <el-table-column label="插入耗时平均值(秒)" prop="avgSaveTime" align="center" width="180" />
        <el-table-column label="插入速度平均值(条/秒)" prop="avgSpeed" align="center" width="180" />
        <el-table-column label="插入总数(条)" prop="totalCount" align="center" width="180" />
        <el-table-column label="更新日期" prop="updateTime" align="center" width="180" />
        <el-table-column label="解析状态" align="center" width="180">
          <template #default="scope">
            <el-tag v-if="scope.row.status === 1" type="success">解析成功</el-tag>
            <el-tag v-else-if="scope.row.status === 2" type="warning">解析中</el-tag>
            <el-tag v-else-if="scope.row.status === 3" type="danger">解析失败</el-tag>
            <el-tag v-else-if="scope.row.status === 4" color="#d6b8ff" effect="light">
              入库中
            </el-tag>
            <el-tag v-else type="info">未解析</el-tag>
          </template>
        </el-table-column>
        <el-table-column fixed="right" label="操作" align="center" width="150">
          <template #default="scope">
            <el-button
              type="primary"
              size="small"
              link
              icon="Mouse"
              @click.prevent="handleParse(scope.row)"
            >
              解析
            </el-button>
            <el-button
              type="danger"
              size="small"
              link
              icon="RefreshLeft"
              @click.prevent="resetPosition(scope.row.id)"
            >
              重置
            </el-button>
          </template>
        </el-table-column>
      </el-table>

      <pagination
        v-if="total > 0"
        v-model:total="total"
        v-model:page="queryParams.pageNum"
        v-model:limit="queryParams.pageSize"
        @pagination="fetchData"
      />
    </el-card>
  </div>
</template>

<script setup lang="ts">
import { ref, reactive, onMounted } from "vue";
import { ElMessage, ElMessageBox } from "element-plus";
import DbSourceAPI from "@/api/mysql/dbsource.api";
import BinLogAPI, { BinLogPageQuery, BinLogPageVO } from "@/api/mysql/binlog.api";

defineOptions({
  name: "BinLog",
  inheritAttrs: false,
});

// 表单和表格引用
const queryFormRef = ref<InstanceType<any>>();
const dataTableRef = ref<InstanceType<any>>();

// 状态管理
const loading = ref(false);
const total = ref(0);
const ids = ref<number[]>([]);

// 查询参数（初始化默认值，避免undefined）
const queryParams = reactive<BinLogPageQuery>({
  pageNum: 1,
  pageSize: 10,
  dbId: undefined,
});

// 表格数据（初始化为空数组，避免类型错误）
const binLogList = ref<BinLogPageVO[]>([]);
const dbSourceOptions = ref<OptionType[]>([]);

// 获取数据库列表
const fetchDbSource = async () => {
  try {
    dbSourceOptions.value = await DbSourceAPI.getOptions();
  } catch (error) {
    ElMessage.error("获取数据库列表失败");
    console.error("数据库列表获取失败:", error);
  }
};

// 获取BinLog列表数据
const fetchData = async () => {
  loading.value = true;
  try {
    const response = await BinLogAPI.getPage(queryParams);
    binLogList.value = response.list || [];
    total.value = response.total || 0;
  } catch (error) {
    ElMessage.error("获取BinLog数据失败");
    console.error("BinLog数据获取失败:", error);
  } finally {
    loading.value = false;
  }
};

// 搜索处理
const handleQuery = () => {
  queryParams.pageNum = 1;
  fetchData();
};

// 重置查询
const handleResetQuery = () => {
  if (queryFormRef.value) {
    queryFormRef.value.resetFields();
  }
  queryParams.pageNum = 1;
  queryParams.dbId = undefined;
  fetchData();
};

// 继续查询（复用逻辑）
const continueQuery = () => {
  queryParams.pageNum = 1;
  fetchData();
};

// 选择行变化
const handleSelectionChange = (selection: BinLogPageVO[]) => {
  ids.value = selection.map((item) => Number(item.id)); // 将id转换为数字
};

// 同步BinLog
const updateBinLog = async () => {
  const dataBaseId = queryParams.dbId;
  if (!dataBaseId) {
    ElMessage.warning("请选择数据库");
    return;
  }

  try {
    await ElMessageBox.confirm("确认同步已选数据库?", "警告", {
      confirmButtonText: "确定",
      cancelButtonText: "取消",
      type: "warning",
    });

    loading.value = true;
    await BinLogAPI.syncBinLog(dataBaseId);
    ElMessage.success("同步成功");
    continueQuery();
  } catch (error: any) {
    if (error !== "cancel") {
      // 排除取消操作的错误
      ElMessage.error("同步失败: " + (error.message || "未知错误"));
      console.error("BinLog同步失败:", error);
    } else {
      ElMessage.info("已取消同步");
    }
  } finally {
    loading.value = false;
  }
};

// 解析BinLog
const handleParse = async (row: BinLogPageVO) => {
  if (!row) {
    ElMessage.error("未选中任何数据项");
    return;
  }

  try {
    await ElMessageBox.confirm("确认解析已选中的数据项?", "警告", {
      confirmButtonText: "确定",
      cancelButtonText: "取消",
      type: "warning",
    });

    // 检查状态
    if (row.status === 2 || row.status === 4) {
      ElMessage.error("该文件尚未解析完成，请耐心等待");
      return;
    }

    // 显示提示
    const prevPosition = row.prevPosition || "0";
    ElMessage.primary(
      prevPosition !== "0"
        ? `解析指令已发送，将从[${prevPosition}]位置开始解析，请通过查询按钮查看解析状态`
        : "解析指令已发送，请通过查询按钮查看解析状态"
    );

    // 调用接口（不等待结果，失败时提示）
    BinLogAPI.handleParse(Number(row.id)).catch((err) => {
      ElMessage.error(`解析指令发送失败：${err.message || "未知错误"}`);
    });
  } catch (error: any) {
    if (error !== "cancel") {
      ElMessage.error("操作失败: " + (error.message || "未知错误"));
    } else {
      ElMessage.info("已取消解析");
    }
  }
};

// 重置解析位置
const resetPosition = async (binLogId?: number) => {
  if (!binLogId) {
    ElMessage.error("请选择有效的记录");
    return;
  }

  try {
    await ElMessageBox.confirm("确认重置已选中数据项?", "警告", {
      confirmButtonText: "确定",
      cancelButtonText: "取消",
      type: "warning",
    });

    loading.value = true;
    await BinLogAPI.resetPosition(binLogId);
    ElMessage.success("重置成功");
    continueQuery();
  } catch (error: any) {
    if (error !== "cancel") {
      ElMessage.error("重置失败: " + (error.message || "未知错误"));
      console.error("重置位置失败:", error);
    } else {
      ElMessage.info("已取消重置");
    }
  } finally {
    loading.value = false;
  }
};

// 页面挂载时初始化
onMounted(() => {
  fetchDbSource();
  handleQuery();
});
</script>

<style lang="scss" scoped>
.data-table__toolbar--actions {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 16px;
}

.data-table__tip {
  margin-left: auto;
  font-size: 12px;
  color: #909399;
}

.search-container {
  margin-bottom: 16px;
}
</style>
